package com.avic.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.avic.gateway.common.constant.GatewayConstant;
import com.avic.gateway.common.util.SpringContextUtil;
import com.avic.gateway.common.util.ex.BizErrorCode;
import com.avic.gateway.model.GatewayResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ExecutionStatus;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.ZuulFilterResult;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * 抽象zuul过滤器
 * Created by flamhaze on 2017/7/12.
 */
@Slf4j
public abstract class AbstractZuulFilter extends ZuulFilter {

    protected ObjectMapper objectMapper = SpringContextUtil.getBean(ObjectMapper.class);

    RedisTemplate redisTemplate = SpringContextUtil.getBean(GatewayConstant.REDIS_BEAN_NAME);

    /**
     * 过滤器名
     */
    private String filterName = getClass().getName();

    /**
     * 默认构造函数, 配合 {@link com.netflix.zuul.DefaultFilterFactory#newInstance(Class)} 使用
     */
    protected AbstractZuulFilter() {
    }

    /**
     * @see ZuulFilter#runFilter()
     */
    @Override
    public final ZuulFilterResult runFilter() {
        ZuulFilterResult result;
        long current = System.currentTimeMillis();
        result = super.runFilter();
        long processTime = System.currentTimeMillis() - current;
        if (result.getStatus().equals(ExecutionStatus.SUCCESS)) {
            log.info("通过 {} 过滤器, 消耗时间: {} ms", filterName, processTime);
        } else if (result.getStatus().equals(ExecutionStatus.FAILED)) {
            log.info("被 {} 过滤器拦截, 消耗时间: {} ms", filterName, processTime);
        } else {
            log.info("跳过 {} 过滤器", filterName);
        }
        return result;
    }

    /**
     * @see ZuulFilter#shouldFilter()
     */
    public boolean shouldFilter(String classSimpleName) {
        if (RequestContext.getCurrentContext().get(classSimpleName) == null) {
            return false;
        }
        return (boolean) RequestContext.getCurrentContext().get(classSimpleName);
    }

    protected String blockRequest(RequestContext requestContext, BizErrorCode bizErrorCode, int responseCode) {
        log.info("中断请求");
        requestContext.setResponseStatusCode(responseCode);
        requestContext.setResponseBody(JSONObject.toJSONString((GatewayResponse.initErrorResponse(bizErrorCode))));
        requestContext.setSendZuulResponse(false);
        requestContext.set(FailedRequestPostFilter.class.getSimpleName(), false);
        requestContext.set(LoginCreateTokenPostFilter.class.getSimpleName(), false);
        requestContext.set(FailedRequestPostFilter.class.getSimpleName(), false);
        requestContext.set(ResponseBodyPostFilter.class.getSimpleName(), false);
        return null;
    }

}
